#!/usr/bin/python
# -*- coding: utf-8 -*-

import diffSymbolDB
import glob
import codecs
from xml.dom.minidom import parse
import xml.dom.minidom

def clean_symbol_name(symbol):
    post = symbol.find("@@")
    if post != -1:
        return symbol[:post]
    return symbol

def ScanReportDir(filepath):
    filelist=glob.glob(filepath)
    return filelist

def DeleteSpecialChar(xmlpath):
    with  codecs.open(xmlpath,"r","utf-8") as filehandle:
        content=filehandle.read()
        if not content.find("<built-in>") ==-1:
            dailtext=content.replace("<built-in>","built-in")
            return dailtext
        else:
            return content

def ContentIsXmlFormat(content):
    try:
        return xml.dom.minidom.parseString(content)
    except Exception as e:
        return None

def LibIscompatible(root):
    test_results=root.getElementsByTagName("test_results")
    if test_results.length <=0:
        return False
    else:
        result=test_results.item(0)
        #print("verdict: "+ result.getElementsByTagName("verdict").item(0).firstChild.data)
        return result.getElementsByTagName("verdict").item(0).firstChild.data == "compatible"


def GetBinaryReport(root):
    report=root.getElementsByTagName("report")
    for item in report:
        print("kind :%s" % item.getAttribute("kind"))
        if not item.getAttribute("kind")=="binary":
            continue
        return item
    return None

def GetProblemsByTypes(binary_report,Types):
    results=binary_report.getElementsByTagName(Types)
    for item in results:
        severity=item.getAttribute("severity")
        print(Types +" severity : " + severity)
        header=item.getElementsByTagName("header")
        if header.length == 0:
            continue


def GetAddSymbols(binary_report, old_lib, new_lib):
    added_symbols = binary_report.getElementsByTagName("added_symbols")
    for added_symbol in added_symbols:
        headers = added_symbol.getElementsByTagName("header")
        if headers.length == 0:
            continue
        print("added_symbols: %d " % (headers.length))
        for header in headers:
            name = header.getAttribute("name")
            libraries = header.getElementsByTagName("library")
            for library in libraries:
                add_symbol_names = library.getElementsByTagName("name")
                for name_element in add_symbol_names:
                    symbol = name_element.firstChild.data
                    symbol = clean_symbol_name(symbol)
                    diffSymbolDB.insertLibSymbolDiffValue2Table(old_lib, new_lib, symbol, "AddSymbols", "", name, 0)

def GetRemoveSymbols(binary_report, old_lib, new_lib):
    removed_symbols = binary_report.getElementsByTagName("removed_symbols")
    for removed_symbol in removed_symbols:
        heard_file = removed_symbol.getElementsByTagName("header")
        if heard_file.length == 0:
            continue
        print("RemoveSymbols:%d " % (heard_file.length))
        for item in heard_file:
            name = item.getAttribute("name")  # header name
            print("headfile :%s" % (name))
            library = item.getElementsByTagName("library")[0]
            remove_symbols_name = library.getElementsByTagName("name")
            for symbol_name in remove_symbols_name:  # Change variable name here
                print(" %s" % (symbol_name.firstChild.data))
                symbol = symbol_name.firstChild.data
                symbol = clean_symbol_name(symbol)
                diffSymbolDB.insertLibSymbolDiffValue2Table(old_lib, new_lib, symbol,
                                                            "RemoveSymbols", 'symbol changes may cause ELF files to malfunction', name, 0)
            print("    ")

def GetSymbolsChanges(binary_report,old_lib,new_lib):
    SymbolsChanges=binary_report.getElementsByTagName("problems_with_symbols")
    for symbols_change in SymbolsChanges:
        severity=symbols_change.getAttribute("severity")
        if severity=="" or severity == None:
            continue
        header_file=symbols_change.getElementsByTagName("header")
        
        if header_file.length == 0:
            continue
        print("%s %d severity:%s " % ("problems_with_symbols",header_file.length,severity))
        for header in header_file:
            name=header.getAttribute("name")
            print(" name: %s" % name)
            librarys= header.getElementsByTagName('library')
            for library in librarys:
                symbols =library.getElementsByTagName("symbol")
                for symbol in symbols:
                    symbol_name=symbol.getAttribute("name") 
                    symbol_name=clean_symbol_name(symbol_name)
                    print("  symbol: %s" % symbol_name)
                    problems =symbol.getElementsByTagName("problem")
                    for problem in problems:
                        id = problem.getAttribute("id")
                        change=problem.getElementsByTagName("change")
                        effect=problem.getElementsByTagName("effect")
                        # print("  id:%s" % id)
                        # print("  change:%s" % change[0].firstChild.data)
                        # print("  effect:%s" % effect[0].firstChild.data)   
                        diffSymbolDB.insertLibSymbolDiffValue2Table(old_lib,new_lib,symbol_name,"Change",change[0].firstChild.data,name,0)
                        print("   ")
                    print("   ") 
            print(" -----  -----  ----- -----  -----  -----  -----  -----  -----  -----  -----  -----")

def GetDataTypeChanges(binary_report,old_lib,new_lib):
    DataTypeChanges=binary_report.getElementsByTagName("problems_with_types")
    for data_type_change in DataTypeChanges:
        severity=data_type_change.getAttribute("severity")
        if severity =="" or severity == None:
            continue
        header_files=data_type_change.getElementsByTagName("header")
        if header_files.length == 0:
            continue
        print("%s %d severity:%s " % ("problems_with_types",header_files.length,severity))
        for header in header_files:
            name=header.getAttribute("name")
            #print(" name: %s" % name)
            types = header.getElementsByTagName("type")
            for type in types:
                symbol= type.getAttribute("name")
                #print("  symbol: %s " % symbol)
                problems=type.getElementsByTagName("problem")
                change=''
                if problems.length != 0:
                    change=problems[0].getElementsByTagName("change")[0].firstChild.data
                diffSymbolDB.insertLibSymbolDiffValue2Table(old_lib,new_lib,symbol+"[data]",'Change',change,name,0)
                affected = type.getElementsByTagName("affected")
                for affected_node in affected:
                    affected_symbols = affected_node.getElementsByTagName("symbol")
                    for affected_symbol in affected_symbols:
                        symbol_name = affected_symbol.getAttribute("name")
                        symbol_name = clean_symbol_name(symbol_name)
                        comment = affected_symbol.getElementsByTagName("comment")[0].firstChild.data
                        diffSymbolDB.insertLibSymbolDiffValue2Table(old_lib,new_lib,symbol_name,'Change',comment,name,0)
        print(" -----  -----  ----- -----  -----  -----  -----  -----  -----  -----  -----  -----")
            
def GetConstantsChange(binary_report,old_lib,new_lib):
    ConstantsChanges = binary_report.getElementsByTagName("problems_with_constants")
    for constants_change in ConstantsChanges:
        severity=constants_change.getAttribute("severity")
        if severity =="" or severity == None:
            continue
        if severity != "Low":
            print(" ConstantsChanges %s " % type(constants_change))

def ParseXmlEleMent2DB(xmlpath,old_lib,new_lib):
    
    content = DeleteSpecialChar(xmlpath)
    dom=ContentIsXmlFormat(content)
    if  dom == None:
        print("parse xml faild : %s" % xmlpath)
        return False
    
    root=dom.documentElement
    binary_report = root
    # print("root %s" % root)
    # binary_report=GetBinaryReport(root)
    # if binary_report == None:
    #     print("get binary report faild %s " % xmlpath)
    #     return False
    
    # if LibIscompatible(binary_report):
    #     #diffSymbolDB.insertLibSymbolDiffValue2Table(old_lib,new_lib,'None','None','None',1)
    #     return True
    if LibIscompatible(binary_report):
        # 将兼容的文件名写入文本文件
        with open("compatible_libraries.txt", "a") as f:
            f.write("{} is compatible with {}\n".format(old_lib,new_lib))
        return True
    print("ParseXmlPath: " +xmlpath)
    GetRemoveSymbols(binary_report,old_lib,new_lib)
    GetSymbolsChanges(binary_report,old_lib,new_lib)
    GetDataTypeChanges(binary_report,old_lib,new_lib)
    GetAddSymbols(binary_report,old_lib,new_lib)
    #GetConstantsChange(binary_report,old_lib,new_lib)
    

def ParseXmlFile(xmlpathlist):
    for xmlitem in xmlpathlist:
        ParseXmlEleMent2DB(xmlitem+"/X_to_Y/compat_report.xml",'a','b')
        print("     ")
